import { useEffect, useRef, useState } from 'react';
import AMapLoader from '@amap/amap-jsapi-loader';
import '@amap/amap-jsapi-types';
import { MarkerClustererOptions } from '@amap/amap-jsapi-types/plugins/MarkerClusterer';
import { LayerType } from '#/enmu.ts';
import { App } from 'antd';

interface MapConfig {
  containerId: string;
  zoom?: number;
  viewMode?: string;
  center?: [number, number];
  mapStyle?: string;
}

export const useMap = ({
  containerId,
  zoom = 10,
  // viewMode 设置为 3D 时添加 marker 的 label 会出现偏移现象
  viewMode = '3D',
  center = [104.066301, 30.572961],
  mapStyle = 'amap://styles/whitesmoke',
}: MapConfig) => {
  const { message } = App.useApp();
  const mapInstance = useRef<AMap.Map>();
  const trafficLayer = useRef<AMap.TileLayer>();
  const satelliteLayer = useRef<AMap.TileLayer>();

  const [zoomLevel, setZoomLevel] = useState(zoom);

  useEffect(() => {
    AMapLoader.load({
      key: '0a8b186361fb581adb2deeed90da7396',
      version: '2.0',
      plugins: ['AMap.Scale', 'AMap.MouseTool', 'AMap.MarkerCluster', 'AMap.MoveAnimation'],
    })
      .then((AMap) => {
        mapInstance.current = new AMap.Map(containerId, {
          viewMode,
          zoom,
          center,
          mapStyle,
        });

        if (mapInstance.current) {
          // 加载路况图层
          trafficLayer.current = new AMap.TileLayer.Traffic() as AMap.TileLayer;
          // 加载卫星图层
          satelliteLayer.current = new AMap.TileLayer.Satellite() as AMap.TileLayer;

          mapInstance.current.on('zoomend', () => {
            const zoom: number = Number(mapInstance.current!.getZoom().toFixed(0));
            setZoomLevel(zoom);
          });
        }
      })
      .catch((e) => console.log(e));

    return () => {
      mapInstance.current?.destroy();
      mapInstance.current = undefined;
    };
  }, []);

  useEffect(() => {
    mapInstance.current?.setMapStyle(mapStyle);
  }, [mapStyle]);

  const addCustomMarker = (option: AMap.MarkerOptions) => {
    const marker = new AMap.Marker(option);
    // marker.setMap(mapInstance.current);
    mapInstance.current?.add(marker);
    return marker;
  };

  const addCluster = (dataOptions: AMap.Marker[], MarkerClusterOptions: MarkerClustererOptions) => {
    if (!mapInstance.current) return;
    return new AMap.MarkerClusterer(mapInstance.current, dataOptions, MarkerClusterOptions);
  };

  const editLayer = (type: LayerType, isAdd: boolean) => {
    switch (type) {
      case LayerType.Satellite:
        if (!satelliteLayer.current) {
          message.warning('卫星图层不存在，请刷新页面重新加载');
        } else {
          if (isAdd) {
            mapInstance.current?.add(satelliteLayer.current!);
          } else {
            mapInstance.current?.remove(satelliteLayer.current!);
          }
        }
        break;
      case LayerType.Traffic:
        if (!trafficLayer.current) {
          message.warning('交通图层不存在，请刷新页面重新加载');
        } else {
          if (isAdd) {
            mapInstance.current?.add(trafficLayer.current!);
          } else {
            mapInstance.current?.remove(trafficLayer.current!);
          }
        }
        break;
    }
  };

  const changePitch = (pitch: number, immediately: boolean = false, duration?: number) => {
    if (mapInstance.current) {
      mapInstance?.current.setPitch(pitch, immediately, duration);
    }
  };

  const changeZoom = (isZoomIn: boolean) => {
    if (isZoomIn) {
      mapInstance.current?.zoomIn();
    } else {
      mapInstance.current?.zoomOut();
    }
  };

  const addPolyline = (path: number[][]) => {
    if (!mapInstance.current) return;
    const line = new AMap.Polyline({
      // map: mapInstance.current,
      path: path as AMap.LngLatLike[],
      showDir: true,
      strokeColor: '#28F', //线颜色
      // strokeOpacity: 1,     //线透明度
      strokeWeight: 6, //线宽
      // strokeStyle: "solid"  //线样式
    });

    mapInstance.current.add(line);

    return line;
  };

  type TextOption = {
    content: string;
    position: [number, number];
    style: Record<string, any>;
  };

  const addText = ({ content, position, style }: TextOption) => {
    const label = new AMap.Text({
      text: content,
      anchor: 'center', // 设置文本标记锚点
      cursor: 'pointer',
      angle: 10,
      style: style,
      position: position,
      offset: new AMap.Pixel(30, 0),
    });

    mapInstance.current?.add(label);

    return label;
  };

  return {
    mapInstance,
    zoomLevel,
    addCustomMarker,
    addCluster,
    editLayer,
    changePitch,
    changeZoom,
    addPolyline,
    addText,
  };
};
